package com.atguigu.flow.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.flow.comm.CommJSON;
import com.atguigu.flow.entity.LoginBO;
import com.atguigu.flow.entity.MenuBO;
import com.atguigu.flow.entity.ParamBO;
import com.atguigu.flow.entity.UserListBO;
import com.atguigu.flow.entity.vo.CurrentUser;
import com.atguigu.flow.entity.vo.TokenInfoBO;
import com.atguigu.flow.service.SysApiService;
import com.atguigu.flow.service.UserListService;


import com.atguigu.flow.utils.RsaUtil;
import com.atguigu.flow.utils.SecureUtil;
import com.atguigu.flow.utils.TokenUtils;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

/**
 * @author zhl
 * @create 2021/9/13 14:40
 */
@Api(description="用户管理")
@RequestMapping("/api")
@RestController
@AllArgsConstructor
public class UserController {

    private final UserListService userListService;
    private final RedisTemplate<String, String> redisTemplate;
    private final SysApiService sysApiService;
    final static String SLAT = "loie_api";

    @PostMapping("/changePwd")
    public
    CommJSON changePwd(@RequestBody String msg, @CurrentUser TokenInfoBO tokenInfoBO) {

        CommJSON commJson = new CommJSON();
        try {

            String aesSecureKey = redisTemplate.opsForValue().get(SecureUtil.MD5Encode(String.format("[DataCenter][secretKey][%s]",
                    tokenInfoBO.getToken())));
            String mwMsg = SecureUtil.decryptAES(msg, aesSecureKey);
            LoginBO bo = JSONObject.parseObject(mwMsg, LoginBO.class);

            String user = tokenInfoBO.getUser();
            UserListBO userListBO = userListService.getUserInfoByUser(user);
            String password = userListBO.getPassword();
            if (StringUtils.isNotBlank(password)) {
                String comparePasswd = bo.getCurrentDate() + SLAT + password;
                String enComparePasswd = SecureUtil.MD5Encode(comparePasswd);
                if (StringUtils.isNotBlank(enComparePasswd) && enComparePasswd.equals(bo.getPassword())) {
                    userListService.updateUserByUser(bo.getNewPassword(), user);
                    commJson.setSuc();
                } else {
                    commJson.setError();
                    commJson.setErrorCode("0401");
                    commJson.setErrorMessage("原密码错误，请重试");
                }
            } else {
                commJson.setError();
                commJson.setErrorCode("0402");
                commJson.setErrorMessage("账户异常，请刷新后重试");
            }
        } catch (Exception e) {
            e.printStackTrace();
            commJson.setErrorCode("0403");
            commJson.setErrorMessage("变更密码异常，请刷新后重试");
            commJson.setError();
        }
        return commJson;
    }

    @PostMapping("/getMenu")
    public
    CommJSON getMenu(@RequestBody String msg, @CurrentUser TokenInfoBO tokenInfoBO) {
        CommJSON commJson = new CommJSON();
        try {
            String aesSecureKey = redisTemplate.opsForValue().get(SecureUtil.MD5Encode(String.format("[DataCenter][secretKey][%s]",
                    tokenInfoBO.getToken())));
            System.out.println(aesSecureKey);
            String mwMsg = SecureUtil.decryptAES(msg, aesSecureKey);
            ParamBO paramBO = JSONObject.parseObject(mwMsg, ParamBO.class);

            String user = tokenInfoBO.getUser();
            List<MenuBO> menuBOList;
            if (paramBO.getFlag() == 1) {
                menuBOList = sysApiService.getMenuList();
            } else {
                menuBOList = sysApiService.getMenuListByUser(user);
            }
            JSONArray jsonArray = new JSONArray();
            for (MenuBO bo : menuBOList) {
                JSONObject jsonObject;
                if ("0".equals(bo.getPid())) {
                    jsonObject = (JSONObject) JSONObject.toJSON(bo);
                    jsonObject.put("children", new JSONArray());
                    jsonArray.add(jsonObject);
                } else {
                    for (int i = 0; i < jsonArray.size(); i++) {
                        JSONObject pidJson = jsonArray.getJSONObject(i);
                        if (bo.getPid().equals(pidJson.getString("id"))) {
                            pidJson.getJSONArray("children").add(JSONObject.toJSON(bo));
                        }
                    }

                }
            }
            commJson.setSuc();
            commJson.setData(SecureUtil.encryptAES(jsonArray.toJSONString(), aesSecureKey));
        } catch (Exception e) {
            e.printStackTrace();
            commJson.setErrorCode("0301");
            commJson.setErrorMessage("获取菜单异常，请刷新后重试");
            commJson.setError();
        }
        return commJson;
    }

    @PostMapping("/setAES")
    public
    CommJSON setAes(@RequestBody ParamBO bo, @CurrentUser TokenInfoBO tokenInfoBO) {
        CommJSON commJson = new CommJSON();
        try {
            System.out.println(tokenInfoBO);
            System.out.println(bo);
            String redisKey = SecureUtil.MD5Encode(String.format("[DataCenter][privateKey][%s]", tokenInfoBO.getToken()));
            String privateKey = redisTemplate.opsForValue().get(redisKey);
            String mwMsg = RsaUtil.decrypt(bo.getSecretKey(), privateKey);

            redisKey = SecureUtil.MD5Encode(String.format("[DataCenter][secretKey][%s]",
                    tokenInfoBO.getToken()));

            redisTemplate.opsForValue().set(redisKey, mwMsg);
            commJson.setSuc();
        } catch (Exception e) {
            e.printStackTrace();
            commJson.setErrorCode("0201");
            commJson.setErrorMessage("程序异常（AES)，请刷新后重试");
            commJson.setError();
        }
        return commJson;
    }

    @PostMapping("/logout")
    public
    CommJSON loginOut() {
        CommJSON commJson = new CommJSON();
        commJson.setSuc();
        return commJson;
    }

    @PostMapping("/login")
    public
    CommJSON login(@RequestBody LoginBO bo) {
        CommJSON commJson = new CommJSON();
        try {
            UserListBO userListBO = userListService.getUserInfoByUser(bo.getUserName());
            if (userListBO != null) {
                String id = userListBO.getId();
                String password = userListBO.getPassword();
                System.out.println(userListBO);
                if (StringUtils.isNotBlank(id) && StringUtils.isNotBlank(password)
                        && !"1".equals(userListBO.getIsLocked())) {
                    String comparePasswd = bo.getLoginDate() + SLAT + password;
                    String enComparePasswd = SecureUtil.MD5Encode(comparePasswd);
                    if (StringUtils.isNotBlank(enComparePasswd) && enComparePasswd.equals(bo.getPassword())) {

                        String token = TokenUtils.token(bo.getUserName());
                        System.out.println(token);
                        Map<String, Object> keyMap;

                        keyMap = RsaUtil.initKey();
                        String publicKey = RsaUtil.getPublicKey(keyMap);
                        String privateKey = RsaUtil.getPrivateKey(keyMap);
                        String redisKey = SecureUtil.MD5Encode(String.format("[DataCenter][privateKey][%s]", token));
                        redisTemplate.opsForValue().set(redisKey, privateKey);
                        //System.out.println(redisKey);
                        //System.out.println(privateKey);

                        JSONObject dataJson = new JSONObject();
                        dataJson.put("id", userListBO.getId());
                        dataJson.put("token", token);
                        dataJson.put("token", token);
                        dataJson.put("publicKey", publicKey);
                        dataJson.put("privateKey", privateKey);
                        dataJson.put("name", userListBO.getName());
                        dataJson.put("originId", userListBO.getOriginId());
                        dataJson.put("roleId", userListBO.getRoleId());
                        dataJson.put("customerId", userListBO.getCustomerId());
                        dataJson.put("dataAuthority", userListBO.getDataAuthority());
                        commJson.setData(dataJson);
                        commJson.setSuc();
                    } else {
                        commJson.setError();
                        commJson.setErrorCode("0101");
                        commJson.setErrorMessage("用户或密码错误，请重试");
                    }
                } else {
                    commJson.setError();
                    commJson.setErrorCode("0102");
                    commJson.setErrorMessage("用户不存在或禁止访问，请检查后重试");
                }
            } else {
                commJson.setError();
                commJson.setErrorCode("0102");
                commJson.setErrorMessage("用户不存在或禁止访问，请检查后重试");
            }
        } catch (Exception e) {
            e.printStackTrace();
            commJson.setErrorCode("0103");
            commJson.setErrorMessage("登录异常,请刷新后重试");
            commJson.setError();
        }
        return commJson;
    }
}
